﻿using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Trace;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private Point ReflectLight(Point point)
    {
        var p = double.Parse(this.pTextBox.Text);
        var zS = double.Parse(this.zSTextBox.Text);
        var scale = double.Parse(this.scaleTextBox.Text);

        var xL = point.X;
        var yL = point.Y;
        var zL = (xL * xL + yL * yL) / (2 * p);

        var zF = p / 2;

        var factor = (zS - zL) / (zL - zF) + 1;
        factor *= scale;
        var xS = factor * xL;
        var yS = factor * yL;

        return new Point(xS, yS);
    }

    private void InputChanged(object? sender = null, object? e = null)
    {
        var offsets = new Vector(
            this.inputCanvas.ActualWidth,
            this.inputCanvas.ActualHeight) / 2;

        this.outputCanvas.Strokes.Clear();
        foreach (var inputStroke in this.inputCanvas.Strokes)
        {
            var stroke = inputStroke.Clone();
            for (int i = 0; i < stroke.StylusPoints.Count; i++)
            {
                var stylusPoint = stroke.StylusPoints[i];
                var point = stylusPoint.ToPoint();
                point -= offsets;
                point = ReflectLight(point);
                point += offsets;
                stylusPoint.X = point.X;
                stylusPoint.Y = point.Y;
                stroke.StylusPoints[i] = stylusPoint;
            }
            this.outputCanvas.Strokes.Add(stroke);
        }
    }

    private void ColorChanged(object sender, TextChangedEventArgs e)
    {
        try
        {
            var color = ColorConverter.ConvertFromString(this.colorTextBox.Text);
            this.inputCanvas.DefaultDrawingAttributes.Color = (Color)color;
            this.colorTextBox.Background = Brushes.Transparent;
        }
        catch (FormatException)
        {
            this.colorTextBox.Background = Brushes.Red;
        }
    }

    private void Reset(object? sender = null, RoutedEventArgs? e = null)
    {
        this.colorTextBox.Text = "Black";

        var w = this.inputCanvas.ActualWidth;
        var h = this.inputCanvas.ActualHeight;

        this.inputCanvas.Strokes.Clear();
        this.inputCanvas.Strokes.Add(new Stroke(new([
            new StylusPoint(0, w / 2),
            new StylusPoint(h, w / 2)
        ]), this.inputCanvas.DefaultDrawingAttributes.Clone()));
        this.inputCanvas.Strokes.Add(new Stroke(new([
            new StylusPoint(h / 2, 0),
            new StylusPoint(h / 2, w)
        ]), this.inputCanvas.DefaultDrawingAttributes.Clone()));
        this.InputChanged();
    }

    private void SwitchMode(object? sender = null, RoutedEventArgs? e = null)
    {
        this.inputCanvas.EditingMode = this.inputCanvas.EditingMode switch
        {
            InkCanvasEditingMode.Ink => InkCanvasEditingMode.EraseByStroke,
            InkCanvasEditingMode.EraseByStroke or _ => InkCanvasEditingMode.Ink,
        };
    }
}